#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int gerade(cv::Mat * img, double a, double b, int gray);
int gerade(IplImage * img, double a, double b, int gray);
void help()
{
    cout << "\nThis program demonstrates line finding with the Hough transform.\n"
         "Usage:\n"
         "./houghlines <image_name>, Default is pic1.jpg\n" << endl;
}
int main(int argc, char** argv)
{
const char* filename = argc >= 2 ? argv[1] : "pic1.jpg";
Mat src = imread(filename, 0);
if(src.empty())
{
    help();
    cout << "can not open " << filename << endl;
    return -1;
}
Mat dst, cdst, cdst2;
Point ptt1, ptt2;
ptt1.x = cvRound(750/2);
ptt1.y = cvRound(750/2);
ptt2.x = cvRound(0);
ptt2.y = cvRound(750/2);
line( src, ptt1, ptt2, Scalar(0,255,0), 3, CV_AA);
ptt2.y = cvRound(0);
ptt2.x = cvRound(750/2);
line( src, ptt1, ptt2, Scalar(0,255,255), 3, CV_AA);

//GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );
// set type CV_RGB2GRAY to convert
// RGB image to grayscale
/// Convert it to gray

Canny(src, dst, 30, 200, 3);
cvtColor(dst, cdst, CV_GRAY2BGR);
cvtColor(dst, cdst2, CV_GRAY2BGR);


imshow("Canny", cdst);
#if 1

// Dilate the image
cv::Mat dilated; // the destination image
cv::dilate(dst,dilated,cv::Mat());
// Display the dilated image
cv::namedWindow("Dilated Image");
cv::imshow("Dilated Image",dilated);

cv::Mat eroded; // the destination image
cv::erode(dilated,eroded,cv::Mat());
// Display the eroded image
cv::namedWindow("Eroded Image");
cv::imshow("Eroded Image",eroded);


vector<Vec2f> lines;
HoughLines(eroded, lines, 2, CV_PI/180, 180, 0, 0 );
//cvtColor(eroded, cdst, CV_GRAY2BGR);
for( size_t i = 0; i < lines.size(); i++ )
{
float rho = lines[i][0], theta = lines[i][1];
Point pt1, pt2, pt0, pt00;
double costheta = cos(theta), sintheta = sin(theta), a, b;
double x0 = costheta*rho, y0 = sintheta*rho;
pt1.x = cvRound(x0 + 1000*(-sintheta));
pt1.y = cvRound(y0 + 1000*(costheta));
pt2.x = cvRound(x0 - 1000*(-sintheta));
pt2.y = cvRound(y0 - 1000*(costheta));
pt0.x = cvRound(x0);
pt0.y = cvRound(y0);
pt00.x = cvRound(0);
pt00.y = cvRound(0);

a = (double)(cvRound(y0 + 1000*(costheta))-cvRound(y0))/(double)(cvRound(x0 + 1000*(-sintheta))-cvRound(x0));
b = -a*cvRound(x0)-a*750/2+cvRound(y0)+750/2;

if ((costheta*(x0-375)/sintheta+y0-375) < 10 && (costheta*(x0-375)/sintheta+y0-375) > -10)
  {
//    line( cdst, pt0, pt00, Scalar(250,250,0), 1, CV_AA);
    line( cdst, pt1, pt2, Scalar(255,255,255), 1, CV_AA);
//gerade(&cdst, costheta/sintheta, costheta*(x0)/sintheta+y0, 255);
  //  cout << "costheta= " << costheta << " sintheta=" << sintheta << endl;
  }

}


//Canny(cdst, dst, 30, 200, 3);
//cvtColor(dst, cdst, CV_GRAY2BGR);
//cvtColor(eroded, eroded, CV_GRAY2BGR);

//bitwise_and(const Mat& src1, const Mat& src2, Mat& dst, const Mat& mask=Mat())
try {
        cdst.resize(750,750);
        cdst = ^ cdst;
        cdst = cdst & eroded;
} catch( cv::Exception& e )
{
const char* err_msg = e.what();
std::cout << "##########################################\nexception caught: " << err_msg << std::endl;
}

//bitwise_and(cdst, eroded, cdst, dst);

//bitwise_not(const Mat& src, Mat& dst)¶
//bitwise_not(cdst, cdst);


#else
vector<Vec4i> lines;
HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 );
for( size_t i = 0; i < lines.size(); i++ )
{
    Vec4i l = lines[i];
    line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA);
}
#endif
imshow("source", src);
imshow("detected lines", cdst);
waitKey();
return 0;
}



int gerade(cv::Mat * img, double a, double b, int gray)
{
//y=ax+b
//cvmSet(img, 4, 4, 255);
//cout << "rows: " << img->rows << endl;
img->cols;

    int width = img->cols;
    int height = img->rows;

    for(int i=0;i<width;i++)
    {
        //if ((i*a+b)<(height))
            //img->imageData[(int)((i*a+b)*width + i)] = 255;
            img->at<uchar>((uchar) (i*a+b), i) = 255;
    }
    return 0;
}

int gerade(IplImage * img, double a, double b, int gray)
{
//y=ax+b
    int width = img->width+1;
    int height = img->height;

    for(int i=0;i<width;i++)
    {
        if (((i*a+b)*width + i)<(width*height))
            img->imageData[(int)((i*a+b)*width + i)] = 255;
    }
    return 0;
}
